from flask import Flask, jsonify, render_template, request
from flask_cors import CORS
from neo4j import GraphDatabase, exceptions
import os
import logging

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = Flask(__name__)
CORS(app)  # 允许跨域请求

# 获取项目根目录
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

# Neo4j配置
NEO4J_URI = "bolt://localhost:7687"
NEO4J_USER = "neo4j"
NEO4J_PASSWORD = "123456"  # 替换为你的实际密码

# 初始化Neo4j驱动
try:
    driver = GraphDatabase.driver(
        NEO4J_URI,
        auth=(NEO4J_USER, NEO4J_PASSWORD),
        max_connection_lifetime=3600,
        connection_timeout=30
    )
    # 测试连接
    with driver.session() as session:
        session.run("RETURN 1")
    logger.info("Neo4j连接成功")
except exceptions.ServiceUnavailable:
    logger.error("Neo4j服务未启动，请检查服务状态")
    driver = None
except exceptions.AuthError:
    logger.error("Neo4j认证失败，请检查账号密码")
    driver = None
except Exception as e:
    logger.error(f"Neo4j连接错误: {e}")
    driver = None


@app.route("/")
def index():
    """前端页面入口"""
    try:
        return render_template("index.html")
    except Exception as e:
        logger.error(f"渲染模板失败: {e}")
        return f"模板渲染错误: {e}", 500


@app.route("/api/health")
def health_check():
    """健康检查接口"""
    if driver is None:
        return jsonify({"status": "error", "message": "Neo4j连接失败"}), 500
    return jsonify({"status": "ok", "message": "服务正常"})


@app.route("/api/entities")
def get_entities():
    """获取所有实体"""
    if driver is None:
        return jsonify({"error": "数据库连接失败"}), 500

    try:
        with driver.session() as session:
            result = session.run("""
                MATCH (e:Entity)
                RETURN e.name AS name, size((e)-[]-()) AS connection_count
                ORDER BY connection_count DESC
                LIMIT 200
            """)
            entities = [{
                "id": record["name"],
                "name": record["name"],
                "count": record["connection_count"],
                "type": "ENTITY"
            } for record in result]
        return jsonify(entities)
    except Exception as e:
        logger.error(f"获取实体失败: {e}")
        return jsonify({"error": str(e)}), 500


@app.route("/api/relations")
def get_relations():
    """获取所有关系"""
    if driver is None:
        return jsonify({"error": "数据库连接失败"}), 500

    try:
        with driver.session() as session:
            result = session.run("""
                MATCH (s:Entity)-[r:RELATION]->(t:Entity)
                RETURN s.name AS source, t.name AS target, r.type AS type, r.text AS text
                LIMIT 500
            """)
            relations = [{
                "source": record["source"],
                "target": record["target"],
                "type": record["type"],
                "text": record.get("text", "")
            } for record in result]
        return jsonify(relations)
    except Exception as e:
        logger.error(f"获取关系失败: {e}")
        return jsonify({"error": str(e)}), 500


@app.route("/api/entity/<name>")
def get_entity_details(name):
    """获取实体详情及关联关系"""
    if driver is None:
        return jsonify({"error": "数据库连接失败"}), 500

    try:
        with driver.session() as session:
            # 查询实体基本信息
            entity_result = session.run("""
                MATCH (e:Entity {name: $name})
                RETURN e.name AS name, size((e)-[]-()) AS connection_count
            """, name=name)

            entity_record = entity_result.single()
            if not entity_record:
                return jsonify({"error": f"实体 '{name}' 不存在"}), 404

            # 查询关联关系
            relations_result = session.run("""
                MATCH (e:Entity {name: $name})-[r:RELATION]->(t)
                RETURN t.name AS target, r.type AS type, 'OUTGOING' as direction
                UNION
                MATCH (s)-[r:RELATION]->(e:Entity {name: $name})
                RETURN s.name AS target, r.type AS type, 'INCOMING' as direction
            """, name=name)

            relations = [{
                "target": record["target"],
                "type": record["type"],
                "direction": record["direction"]
            } for record in relations_result]

            return jsonify({
                "entity": {
                    "id": entity_record["name"],
                    "name": entity_record["name"],
                    "count": entity_record["connection_count"],
                    "type": "ENTITY"
                },
                "relations": relations
            })
    except Exception as e:
        logger.error(f"获取实体详情失败: {e}")
        return jsonify({"error": str(e)}), 500


@app.route("/api/search")
def search_entities():
    """搜索实体"""
    if driver is None:
        return jsonify({"error": "数据库连接失败"}), 500

    query = request.args.get('q', '')
    if not query:
        return jsonify([])

    try:
        with driver.session() as session:
            result = session.run("""
                MATCH (e:Entity)
                WHERE e.name CONTAINS $query
                RETURN e.name AS name, size((e)-[]-()) AS connection_count
                ORDER BY connection_count DESC
                LIMIT 50
            """, query=query)

            entities = [{
                "id": record["name"],
                "name": record["name"],
                "count": record["connection_count"],
                "type": "ENTITY"
            } for record in result]

            return jsonify(entities)
    except Exception as e:
        logger.error(f"搜索实体失败: {e}")
        return jsonify({"error": str(e)}), 500


if __name__ == "__main__":
    # 启动服务
    port = int(os.environ.get("PORT", 5000))
    app.run(host="0.0.0.0", port=port, debug=True)